<template>
  <view class="container">
    <view class="box">
      <view 
        class="ball" 
        :style="{
          backgroundColor: currentColor,
          boxShadow: `0 0 20px ${currentColor}, 0 0 30px ${currentColor}, 0 0 40px ${currentColor}`,
		  // transform: `translate(${ballPosition.x}px, ${ballPosition.y}px)`
		  left:`${ballPosition.x}px`,
		  top:`${ballPosition.y}px`
        }"
      ></view>
	  <view class="card-text">
	  	
	  </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

// 定义颜色数组（使用实际的颜色值而非Tailwind类名）
const colors = [
  '#ef4444', // 红色
  '#3b82f6', // 蓝色
  '#22c55e', // 绿色
  '#eab308', // 黄色
  '#8b5cf6', // 紫色
  '#ec4899', // 粉色
];

const currentColor = ref(colors[0]);
const colorProgress = ref(0);
const cycleDuration = 3000; // 每个颜色周期的持续时间(毫秒)
const animationInterval = 16; // 动画更新间隔(约60fps)


// RGB转HSV函数
const rgbToHsv = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;
  
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h, s, v = max;
  
  const d = max - min;
  s = max === 0 ? 0 : d / max;
  
  if (max === min) {
    h = 0; // achromatic
  } else {
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  
  return [h, s, v];
};

// HSV转RGB函数
const hsvToRgb = (h, s, v) => {
  let r, g, b;
  
  const i = Math.floor(h * 6);
  const f = h * 6 - i;
  const p = v * (1 - s);
  const q = v * (1 - f * s);
  const t = v * (1 - (1 - f) * s);
  
  switch (i % 6) {
    case 0: r = v, g = t, b = p; break;
    case 1: r = q, g = v, b = p; break;
    case 2: r = p, g = v, b = t; break;
    case 3: r = p, g = q, b = v; break;
    case 4: r = t, g = p, b = v; break;
    case 5: r = v, g = p, b = q; break;
  }
  
  return [
    Math.round(r * 255),
    Math.round(g * 255),
    Math.round(b * 255)
  ];
};

// 颜色插值函数
const interpolateColors = (color1, color2, progress) => {
  // 转换为RGB值
  const r1 = parseInt(color1.substring(1, 3), 16);
  const g1 = parseInt(color1.substring(3, 5), 16);
  const b1 = parseInt(color1.substring(5, 7), 16);
  
  const r2 = parseInt(color2.substring(1, 3), 16);
  const g2 = parseInt(color2.substring(3, 5), 16);
  const b2 = parseInt(color2.substring(5, 7), 16);
  
  // 转换为HSV进行插值
  const hsv1 = rgbToHsv(r1, g1, b1);
  const hsv2 = rgbToHsv(r2, g2, b2);
  
  // 在HSV空间插值
  let h = hsv1[0] + (hsv2[0] - hsv1[0]) * progress;
  // 处理色相环绕
  if (h > 1) h -= 1;
  if (h < 0) h += 1;
  
  const s = hsv1[1] + (hsv2[1] - hsv1[1]) * progress;
  const v = hsv1[2] + (hsv2[2] - hsv1[2]) * progress;
  
  // 转回RGB
  const rgb = hsvToRgb(h, s, v);
  
  // 转换为十六进制颜色
  return `#${rgb[0].toString(16).padStart(2, '0')}${rgb[1].toString(16).padStart(2, '0')}${rgb[2].toString(16).padStart(2, '0')}`;
};

// 动画计时器
let animationTimer = null;

// 更新颜色渐变
const updateColor = () => {
  colorProgress.value += animationInterval / cycleDuration;
  
  if (colorProgress.value >= 1) {
    colorProgress.value = 0;
  }
  
  // 计算当前颜色索引和下一个颜色索引
  const colorCount = colors.length;
  const currentIndex = Math.floor(colorProgress.value * colorCount);
  const nextIndex = (currentIndex + 1) % colorCount;
  
  // 计算在当前颜色和下一个颜色之间的进度
  const localProgress = (colorProgress.value * colorCount) - currentIndex;
  
  // 插值计算当前颜色
  currentColor.value = interpolateColors(
    colors[currentIndex],
    colors[nextIndex],
    localProgress
  );
};


const ballPosition = ref({ x: -30, y: -30 }); // 初始位置
const ballStatus = ref(1);                  // 1:左, 2:下, 3:右, 4:上
const speed = ref(1);                       // 移动速度
const BOUNDARY = {
  lt: { x: -30, y: -30 },   // 左上
  lb: { x: -30, y: 90 },    // 左下
  rt: { x: 170, y: -30 },   // 右上
  rb: { x: 170, y: 90 }     // 右下
};

// 移动函数 - 左
const moveLeft = () => {
  ballPosition.value.x += speed.value;
  // 到达右边界时切换状态
  if (ballPosition.value.x >= BOUNDARY.rt.x) {
    ballPosition.value.x = BOUNDARY.rt.x;
    ballStatus.value = 2;
  }
};

// 移动函数 - 下
const moveBottom = () => {
  ballPosition.value.y += speed.value;
  // 到达下边界时切换状态
  if (ballPosition.value.y >= BOUNDARY.rb.y) {
    ballPosition.value.y = BOUNDARY.rb.y;
    ballStatus.value = 3;
  }
};

// 移动函数 - 右
const moveRight = () => {
  ballPosition.value.x -= speed.value;
  // 到达左边界时切换状态
  if (ballPosition.value.x <= BOUNDARY.lb.x) {
    ballPosition.value.x = BOUNDARY.lb.x;
    ballStatus.value = 4;
  }
};

// 移动函数 - 上
const moveTop = () => {
  ballPosition.value.y -= speed.value;
  // 到达上边界时切换状态
  if (ballPosition.value.y <= BOUNDARY.lt.y) {
    ballPosition.value.y = BOUNDARY.lt.y;
    ballStatus.value = 1;
  }
};

// 统一更新函数
const updateFrame = () => {
  switch (ballStatus.value) {
    case 1: moveLeft(); break;
    case 2: moveBottom(); break;
    case 3: moveRight(); break;
    case 4: moveTop(); break;
  }
};



// 组件挂载时开始动画
onMounted(() => {
  // 使用setInterval替代requestAnimationFrame
  // animationTimer = setInterval(updateColor, animationInterval);
  animationTimer = setInterval(() => {
      updateFrame();
      updateColor();
    }, animationInterval);
});

// 组件卸载时清除动画
onUnmounted(() => {
  if (animationTimer) {
    clearInterval(animationTimer);
  }
});
</script>

<style scoped>


.box {
	position: relative;
  width: 200px;
  height: 120px;
  /* border: 2px solid #333; */
  border-radius: 8px;
 /* display: flex;
  justify-content: center;
  align-items: center; */
  background-color: #ffffff;
  box-shadow: 
      inset 0 0 0 1px #a2a2a2, /* 内边框 */
      0 0 30px rgba(0, 0, 0, 0.2); /* 原有外阴影 */
  overflow: hidden;
}

.ball {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  position: absolute; 
  transition: all 0.2s ease;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.card-text{
	position: absolute;
	width: calc(100% - 4px);
	height: calc(100% - 4px);
	margin: 2px;
	/* background-color: #4ea8e4; */
	background: url("/static/box/1.png");
	
	border-radius: 8px;
	z-index: 999;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(1);
  }
}
</style>
